package java_thinking.unit_17._17_7_8;

/**
 * @Desc:
 * @author: cww
 * @DateTime: 2019-04-17 23:03
 */

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 用来验证该类是为何不能正常工作在一个HashMap
 * 正确的equals()方法应该满足下列5个条件：
 * 1.自反性，对任意x，x.equals(x)一定返回true；
 * 2.对称性，对任意x和y，如果y.equals(x)返回true，则x.equals(y)也返回true
 * 3.传递性，对任意x\y\z，如果x.equals(y)返回true，y.equals(z)返回true，则x.equals(z)也返回true
 * 4.一致性，对任意x和y，如果对象中用于等价比较的信息没有改变，那么无论安调用多少次x.equals(y)，
 * 返回的结果应该保持一致，要么一直是true，要么一直是false；
 * 5.对任何不适null的x，x.equals(null)一定返回false
 */
class Groundhog {
    protected int number;

    public Groundhog(int number) {
        this.number = number;
    }

    @Override
    public String toString() {
        return "Groundhog{" +
                "number=" + number +
                '}';
    }
}

class Prediction {
    private static Random rand = new Random(47);
    private boolean shadow = rand.nextDouble() > 0.5;

    @Override
    public String toString() {
        if (shadow) {
            return "Six more weeks of Winter";
        } else {
            return "Early Spring!";
        }
    }
}
public class SpringDetector {
    public static <T extends Groundhog> void detecting(Class<T> type) throws Exception {
        Constructor<T> ghog = type.getConstructor(int.class);
        Map<Groundhog,Prediction> map = new HashMap<>();
        for (int i = 0; i < 10; i++) {
            map.put(ghog.newInstance(i),new Prediction());
        }
        System.out.println(map);
        /**
         * ghog中有gh的key，但是还是get不到value，因为Groundhog默认继承自Object，所以这里使用
         * Object的hashCode方法生成散列表，它默认是使用对象的地址计算散列码的，因此第一次生成
         * 的Groundhog域第二次生成的散列码是不同的，所以查不出，必须同时覆写equals和hashCode
         */
        Groundhog gh = ghog.newInstance(3);
        System.out.println("Looking up prediction for " + gh);
        if (map.containsKey(gh)) {
            System.out.println(map.get(gh));
        } else {
            System.out.println("Key not found : " + gh);
        }
    }

    public static void main(String[] args) throws Exception {
        detecting(Groundhog.class);
    }
}
